#![allow(unused_imports)]
// use std::fs;
use serde::{Serialize, Deserialize} ;
use serde_json::{json, Value as JsonValue} ;

use avro_lib_rust::schema::{self, Schema as AvroSchema} ;
use avro_lib_rust::json::decode_avro_json ;
use anyhow::Result ;

use tracing::{debug, error, info, span, warn, Level};
use tracing_subscriber::FmtSubscriber;

fn main() -> Result<()> {
    let (non_blocking, _guard) = tracing_appender::non_blocking(std::io::stdout());
    tracing_subscriber::fmt().with_writer(non_blocking).init();

    let schema_json = serde_json::from_reader::<_, JsonValue>(std::fs::File::open("larluo.avsc")?).unwrap() ;
    let avro_schema = AvroSchema::parse_json(&schema_json).unwrap() ;
    let avro_json = serde_json::from_reader::<_, JsonValue>(std::fs::File::open("larluo.json")?).unwrap() ;

    use std::sync::* ;

    #[derive(Clone)]
    struct BytesWriter (Arc<Mutex<Vec<u8>>>);
    impl BytesWriter {
        fn bytes(&self) -> Vec<u8> {
            let buf = self.0.lock().unwrap() ;
            buf.clone()
        }
    }
    impl std::io::Write for BytesWriter {
        fn write(&mut self, bs: &[u8]) -> std::io::Result<usize> {
            let mut buf = self.0.lock().unwrap() ;
            buf.write(bs)
        }
        fn flush(&mut self) -> std::io::Result<()> { Ok(()) }
    }
    let writer = BytesWriter(Arc::new(Mutex::new(Vec::new()))) ;
    let (non_blocking, _guard) = tracing_appender::non_blocking(writer.clone());
    let subscriber = tracing_subscriber::fmt().with_max_level(Level::TRACE).with_writer(non_blocking);
    let avro_value = tracing::subscriber::with_default(subscriber.finish(), || {
        decode_avro_json(&avro_schema, &avro_json)
    }) ;

    avro_value.unwrap() ;
    println!("larluo: [\n{}\n]", std::str::from_utf8(&writer.bytes()).unwrap()) ;
    
    Ok(())
}
